<?php

namespace app\index\controller;

use think\Controller;

/**
 * EPC操作类
 * @package app\index\controller
 */
class Epc extends Controller
{
    private $error = null;

    private $cmd_change_rfid = [
        'AA 00 A8 00 03 00 01 01 AD DD', // 切换到第 1 根天线
        'AA 00 A8 00 03 00 02 01 AE DD', // 切换到第 2 根天线
        'AA 00 A8 00 03 00 04 01 B0 DD', // 切换到第 3 根天线
        'AA 00 A8 00 03 00 08 01 B4 DD', // 切换到第 4 根天线
        'AA 00 A8 00 03 00 10 01 BC DD', // 切换到第 5 根天线
        'AA 00 A8 00 03 00 20 01 CC DD', // 切换到第 6 根天线
        'AA 00 A8 00 03 00 40 01 EC DD', // 切换到第 7 根天线
        'AA 00 A8 00 03 00 80 01 2C DD', // 切换到第 8 根天线
        'AA 00 A8 00 03 01 00 01 AD DD', // 切换到第 9 根天线
        'AA 00 A8 00 03 02 00 01 AE DD', // 切换到第 10 根天线
        'AA 00 A8 00 03 04 00 01 B0 DD', // 切换到第 11 根天线
        'AA 00 A8 00 03 08 00 01 B4 DD', // 切换到第 12 根天线
        'AA 00 A8 00 03 10 00 01 BC DD', // 切换到第 13 根天线
        'AA 00 A8 00 03 20 00 01 CC DD', // 切换到第 14 根天线
        'AA 00 A8 00 03 40 00 01 EC DD', // 切换到第 15 根天线
        'AA 00 A8 00 03 80 00 01 2C DD', // 切换到第 16 根天线
        'AA 00 A8 00 03 FF FF 01 AA DD', // 切换到全部天线
    ];

    private $cmd_batch_get = 'AA 00 22 00 00 22 DD'; // 轮询标签

    public function getError()
    {
        return $this->error;
    }

    public function initialize()
    {
        if (!defined('ROOT_PATH')) {
            define('ROOT_PATH', str_replace('\\', '/', env('root_path')));
        }
    }

    public function index()
    {
        // 切换天线
        $this->send_msg($this->cmd_change_rfid[10]);
        sleep(1);

        // 发送轮询指令
        $this->send_msg($this->cmd_batch_get);
        echo "success";
    }

    public function report_epc($msg)
    {
        // 正确返回设备
        //  AA		02		22		01		11		C9		34		00		30751FEB705C5904E3D50D70
        //  帧头	    通知	    轮询	    天线	    参数长	RSSI	PC高	PC低	EPC高				EPC低
        //  3A		76		F0		DD
        //  CRC高	CRC低	校验	结束

        //  AA		01		FF		01		01		15		17		DD
        //  帧头	    响应	    指令	    天线	    参数长	参数	    校验	    结束

        // TODO 逻辑处理
    }

    private function send_msg($msg, $program_check = true)
    {
        // 串口通信程序接口地址
        $serial_path = ROOT_PATH . '/extend/epc/';

        $msg_file = $serial_path . '/conf/send_msg';

        // 串口通信程序状态检查
        if (!session('epc_start') && $program_check && !$this->serialProgramCheck($serial_path)) {
            $this->error = 'EPC通信程序未正确运行';
            return false;
        }

        // 将指令写入串口通信程序接口文件中，该程序能自动读取并发送指令
        $fp = fopen($msg_file, 'w');
        fwrite($fp, str2hex($msg));
        fclose($fp);
        return true;
    }

    /**
     * 检查串口通信程序
     * @param string $serial_path 通信文件路径
     * @return bool
     */
    private function serialProgramCheck($serial_path)
    {
        session('epc_start', true);
        $msg_file = $serial_path . '/conf/send_msg';

        // 通信文件存在，则删除
        if (is_file($msg_file)) unlink($msg_file);
        usleep(200000); // 删除完等待0.2秒

        // 如果通信文件被正常创建，则程序正常
        if (is_file($msg_file)) return true;

        // 检查通信程序启动文件
        if (!is_file($serial_path . '/start_epc.vbs')) {
            $this->error = 'EPC启动程序丢失';
            return false;
        }

        $cmd = "cd $serial_path && start start_epc.vbs && exit 2>&1";
        exec($cmd);
        usleep(200000); // 删除完等待0.2秒
        if (is_dir($serial_path)) deleteDir("$serial_path/%SystemDrive%");

        // 再次检查通信文件是否被正常创建
        if (is_file($msg_file)) return true;

        $this->error = 'EPC通信程序未正确运行';
        return false;
    }
}
